﻿//============================================================================
// 目前只支持双光源的Compact系列设备
//============================================================================

#include "optodemo.h"
#include <iostream>
#include <Windows.h>    //for Sleep

OptoDemo::OptoDemo(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::OptoDemoClass())
{
    ui->setupUi(this); 

    //读取ini，时间低于3s的设置为3s
    settings = new QSettings("config.ini", QSettings::IniFormat);
    camera = settings->value("/device/camera").toString().toStdString();     //设备
    time = settings->value("/clock/time").toInt();                           //时间
    if (time < 3)
    {
        time = 3;
    }
    Ring_Power= settings->value("/device/Ring_Power").toInt();
    Coax_Power = settings->value("/device/Coax_Power").toInt();
    Ring_ExposureTime= settings->value("/device/Ring_ExposureTime").toDouble();
    Coax_ExposureTime = settings->value("/device/Coax_ExposureTime").toDouble();
    Red= settings->value("/whiteBalance/Red").toInt();
    Green = settings->value("/whiteBalance/Green").toInt();
    Blue = settings->value("/whiteBalance/Blue").toInt();


    ui->label_2->setText(QString("正在加载设备%1，请稍等……").arg(QString::fromStdString(camera)));
}

OptoDemo::~OptoDemo()
{
    delete ui;
}

void OptoDemo::work()
{
    //QCoreApplication::processEvents();

    //时钟，切换属性
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &OptoDemo::onTimeout);
    flag = true;    //切换属性标志

    //Opto资源初始化
    Opto::Framework::initialize();
    //查找并载入驱动
    //path driversPath = path(getenv("OPTOSDKDIR")) / "bin" / "x64" / "vc15" / "release" / "drivers";
    path driversPath = "drivers";   //针对没有安装sdk的电脑，注意更改路径。并拷贝到项目目录和exe目录。
    Opto::DevicesManager::discoverDrivers(driversPath.string());
    Opto::DevicesManager::loadAllDrivers();
    //查找插入电脑的设备是否有compactM SN-IC10-00003
    Opto::Module::autoDiscoverModules();
    std::vector<Opto::ModuleInfos> vecModulesInfos = Opto::Module::enumerateModules(Opto::Module::ModuleEnumerateMethod::Ready);
    int i = 0;
    bool isCompactM_SN_IC10_00003 = false;
    for (int i = 0; i < vecModulesInfos.size(); i++)
    {
        Opto::ModuleInfos modInfos = vecModulesInfos.at(i);
        //std::cout << i << " : " << modInfos.name << " " << modInfos.product << "_" << modInfos.model << "_(" << modInfos.serial << ")" << "\n";
        if (modInfos.name == camera)
        {
            isCompactM_SN_IC10_00003 = true;
        }
    }
    if (!isCompactM_SN_IC10_00003)      //如果没有compactM SN-IC10-00003，直接退出
    {
        ui->label_2->setText(QString("未找到设备 %1，退出！").arg(QString::fromStdString(camera)));
        QCoreApplication::processEvents();  //提示信息更新到界面
        Opto::Framework::close();       //释放资源
        Sleep(2000);
        exit(0);
        return;
    }
    //打开compactM SN-IC10-00003    
    std::string camName = camera;
    module.open(camName);

    //设置灯属性，此时灯亮起
    module.setAttributeValue("Light::Type", (int)1);		//0同轴，1环形
    //module.setAttributeValue("Light::Power", (int)80);      //同轴时 Power 30，曝光 15；环形时 Power 80，曝光 35
    module.setAttributeValue("Light::Power", Ring_Power);

    //只连接一个相机时，camName变更为 “Camera”
    camName = "Camera";
    //设置具体相机的属性
    module.setAttributeValue("Camera::AcquisitionControl::ExposureAuto", false);            //曝光
    //module.setAttributeValue("Camera::AcquisitionControl::ExposureTime", 35.0);
    //module.setAttributeValue("Camera::AnalogControl::BalanceWhiteAuto", (int)1);            //白平衡。1手动，0自动
    //module.setAttributeValue("Camera::AnalogControl::BalanceRatioRed", (int)19);
    //module.setAttributeValue("Camera::AnalogControl::BalanceRatioGreen", (int)5);
    //module.setAttributeValue("Camera::AnalogControl::BalanceRatioBlue", (int)65);
    module.setAttributeValue("Camera::AcquisitionControl::ExposureTime", Ring_ExposureTime);
    module.setAttributeValue("Camera::AnalogControl::BalanceWhiteAuto", (int)1);            //白平衡。1手动，0自动
    module.setAttributeValue("Camera::AnalogControl::BalanceRatioRed", Red);
    module.setAttributeValue("Camera::AnalogControl::BalanceRatioGreen", Green);
    module.setAttributeValue("Camera::AnalogControl::BalanceRatioBlue", Blue);

    //拉流，缓存1帧
    module.setupCameraAcquisition("Camera", true, 1);
    module.startCameraAcquisition("Camera");

    //启动切换
    timer->start(time * 1000);
    hide(); //隐藏启动界面

    //界面
    //Opto::DisplayWindow window;
    window.create("Window");
    window.move(Opto::Point2d(0, 0));
    //window.resize(1280, 1024);
    window.resize(1920, 1010);
    window.setZoomToFit();  //图像适应窗口
    // display snapshot mode 
    // - true: the display window makes an internal copy of the image, 
    // - false: the display window has no internal copy of the image
    window.setSnaphotMode(false);

    //图像
    Opto::Image::Type type;
    int width, height, bitsPixel, bytesPixel;
    module.cameraImageInfos(camName, &type, &width, &height, &bitsPixel, &bytesPixel);
    //Opto::Image image;
    image.create(type, width, height);

    bool running = true;
    while (running)
    {
        QCoreApplication::processEvents();  //防止阻塞timer
        try
        {
            // acquire image
            int timeoutMs = 5000;
            unsigned long long grabbedBuffer = 0;
            module.grabCameraImage(camName, image, Opto::Module::BufferMode::Next, 0, &grabbedBuffer, timeoutMs);
            //std::cout << "Buffer " << std::to_string(grabbedBuffer) << " acquired\n";
            
            if (toShow)
            {
                // display image, wait for key press with 50ms timeout
                window.displayImage(image, std::string("Press any key to exit..."));
            }

            if (window.waitKey(50) == OptoErrorSuccess)
            {
                running = false; // exit loop if key pressed
                timer->stop();
            }               
                
        }
        catch (Opto::Exception& e)
        {
            //std::cout << "Grab error code: " << std::to_string(e.code()) << ", description: " << e.message();
            running = false; // exit loop if error
            timer->stop();
        }
        
    }
    

    module.stopCameraAcquisition("Camera");
    module.cleanupCameraAcquisition("Camera");

    window.close();
    image.destroy();
    module.close();

    Opto::Framework::close();       //释放资源

    exit(0);                        //退出程序
}


void OptoDemo::onTimeout()
{
    toShow = false;     //切换完，再展示。防止灯闪烁时屏幕画面也闪
    flag = !flag;
    if (flag)
    {
        //try
        {                 
            module.setAttributeValue("Light::Type", (int)1);		//0同轴，1环形
            //module.setAttributeValue("Light::Power", (int)80);
            //module.setAttributeValue("Camera::AcquisitionControl::ExposureTime", 35.0);
            module.setAttributeValue("Light::Power", Ring_Power);   //该值改变，灯光会闪烁（先黑再亮）
            module.setAttributeValue("Camera::AcquisitionControl::ExposureTime", Ring_ExposureTime);
        }
        //catch (const std::exception&)
        {

        }
    }
    else
    {
        //try
        {              
            module.setAttributeValue("Light::Type", (int)0);		//0同轴，1环形
            //module.setAttributeValue("Light::Power", (int)30);
            //module.setAttributeValue("Camera::AcquisitionControl::ExposureTime", 15.0);
            module.setAttributeValue("Light::Power", Coax_Power);   //该值改变，灯光会闪烁（先黑再亮）
            module.setAttributeValue("Camera::AcquisitionControl::ExposureTime", Coax_ExposureTime);            
        }
        //catch (const std::exception&)
        {

        }
    }
    //Sleep(100);
    toShow = true;
}

#include<QtConcurrent/QtConcurrent>
void OptoDemo::runFuc()
{
    QtConcurrent::run(this, &OptoDemo::work);
}
